﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using TaskStatus = TaskQueueDemo.ViewModel.TaskStatus;
namespace TaskQueueDemo.ViewModels
{
    public class TaskQueueManager : INotifyPropertyChanged
    {
        private readonly ObservableCollection<TaskItem> _tasks = new ObservableCollection<TaskItem>();
        public IReadOnlyCollection<TaskItem> Tasks => _tasks;

        private int _maxConcurrentTasks = 1;
        public int MaxConcurrentTasks
        {
            get => _maxConcurrentTasks;
            set
            {
                _maxConcurrentTasks = value;
                OnPropertyChanged();
                StartProcessing(); // 当并发数改变时尝试启动新任务
            }
        }



        private readonly ConcurrentDictionary<TaskItem, bool> _runningTasks = new ConcurrentDictionary<TaskItem, bool>();
        public int RunningTaskCount => _runningTasks.Count;

        public void AddTask(string taskName, Action<CancellationToken, IProgress<int>> taskAction)
        {
            var taskItem = new TaskItem
            {
                Name = taskName,
                Status = TaskStatus.Pending
            };

            var progress = new Progress<int>(p => taskItem.Progress = p);

            taskItem.TaskAction = () =>
            {

                taskAction(taskItem.CancellationTokenSource.Token, progress);
            };

            _tasks.Add(taskItem);
            //StartProcessing();
        }

        public void StartProcessing()
        {
            // 计算可以启动的新任务数量
            int availableSlots = MaxConcurrentTasks - RunningTaskCount;

            for (int i = 0; i < availableSlots; i++)
            {
                var nextTask = _tasks.FirstOrDefault(t => t.Status == TaskStatus.Pending);
                if (nextTask == null) break;

                StartTask(nextTask);
            }
        }

        private async void StartTask(TaskItem task)
        {
            task.Status = TaskStatus.Running;
            _runningTasks[task] = true;
            OnPropertyChanged(nameof(RunningTaskCount));

            try
            {
                await Task.Run(() =>
                {
                    //task.PreProcess();
                    //task.Process();
                    task.TaskAction?.Invoke();
                });

                task.Status = TaskStatus.Completed;
            }
            catch (OperationCanceledException)
            {
                task.Status = TaskStatus.Failed;
                task.Progress = 0;
            }
            catch
            {
                task.Status = TaskStatus.Failed;
            }
            finally
            {
                _runningTasks.TryRemove(task, out _);
                OnPropertyChanged(nameof(RunningTaskCount));
                StartProcessing(); // 任务完成后尝试启动新任务
            }
        }

        public void StopAllTasks()
        {
            foreach (var task in _tasks)
            {
                if (task.Status == TaskStatus.Running || task.Status == TaskStatus.Pending)
                {
                    task.Cancel();
                }
            }
            _runningTasks.Clear();
            OnPropertyChanged(nameof(RunningTaskCount));
        }

        public void ClearCompletedTasks()
        {
            var completedTasks = _tasks.Where(t => t.Status == TaskStatus.Completed).ToList();
            foreach (var task in completedTasks)
            {
                _tasks.Remove(task);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}